package net.cyue.nest.nestjava.platform.tomcat;

import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import net.cyue.nest.nestjava.common.data.http.HTTPRequestBody;
import net.cyue.nest.nestjava.common.data.http.HTTPRequestParams;
import net.cyue.nest.nestjava.common.enums.RequestMethod;
import net.cyue.nest.nestjava.common.util.InputUtil;
import net.cyue.nest.nestjava.core.adapter.AbstractHTTPRequest;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class TomcatHTTPRequest
  extends AbstractHTTPRequest<HttpServletRequest>
{
  public TomcatHTTPRequest(ServletRequest request) {
    this.request = (HttpServletRequest) request;
    try {
      this.request.setCharacterEncoding("utf-8");
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public String scheme() {
    return this.request.getScheme();
  }

  @Override
  public RequestMethod method() {
    return RequestMethod.valueOf(this.request.getMethod().toUpperCase());
  }

  @Override
  public String uri() {
    return this.request.getRequestURI();
  }

  @Override
  public String path() {
    return this.request.getContextPath();
  }

  @Override
  public HTTPRequestParams params() {
    final var params = this.request.getParameterMap();
    return new HTTPRequestParams(params);
  }

  @Override
  public HTTPRequestBody body() {
    try {
      final var input = this.request.getInputStream();
      String bodyString = null;
      var contentType = this.getHeader("Content-Type");
      if (contentType == null) {
        contentType = "";
      }

      if (contentType.contains("form-data")) {
        String boundary = contentType.split(";")[1].split("=")[1];
        return HTTPRequestBody.fromFormData(boundary, input);
      } else {
        bodyString = InputUtil.readString(input);
      }

      if (contentType.contains("application/json")) {
        return HTTPRequestBody.fromJSONString(bodyString);
      } else {
        return HTTPRequestBody.fromQueryString(bodyString);
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public String getHeader(String name) {
    return this.request.getHeader(name);
  }

  @Override
  public String getParameter(String name) {
    return this.request.getParameter(name);
  }
}
